#ifndef CODECOUNTERTHREAD_H
#define CODECOUNTERTHREAD_H

#include <QString>
#include <QThread>
#include <QList>
#include <QFileInfo>

struct CountResult
{
    int totalLines   = 0;  // 总行数
    int codeLines    = 0;  // 代码总行数
    int commentLines = 0;  // 注释总行数
    int blankLines   = 0;  // 空白总行数
};

struct FileCountResult
{
    QString     fileName;
    QString     path;
    CountResult countInfo;
};

struct LangType
{
    QString     name;
    QStringList fileExtensions;
    QString     singleLineComment;
    QString     multiLineCommentsBegin;
    QString     multiLineCommentsEnd;
};

class CodeCounterWorker;

class CodeCounterThread : public QThread
{
    Q_OBJECT
public:
    CodeCounterThread(QObject* parent = 0);
    ~CodeCounterThread();

    void setLangTypes(const QList<LangType>& langTypes);
    void setSourceDirectory(const QString& sourceDir);
    void setContainsSubDir(bool containsSubDir);

    CodeCounterWorker* worker();

private:
    CodeCounterWorker* mWorker;
    QList<LangType>    mLangTypes;
    QString            mSourceDir;
    bool               mContainsSubDir;

    friend class CodeCounterWorker;
};

class CodeCounterWorker : public QObject
{
    Q_OBJECT

public:
    CodeCounterWorker(CodeCounterThread* thread);

signals:
    void started();
    void stopped();
    void fileFinished(
            const FileCountResult& fileResult, const CountResult& result);
    void finished(const CountResult& result, bool userStop);

public slots:
    void startCount();
    void stopCount();

private slots:
    void process();

private:
    void processFile(const QFileInfo& fileInfo);

private:
    CodeCounterThread* mThread;
    QList<QFileInfo>   mFileInfoList;
    CountResult        mCountResult;
    bool               mUserStop = false;
};

#endif // CODECOUNTERTHREAD_H
